package com.jic.point.service.impl;

import com.alibaba.fastjson.JSON;
import com.jic.common.base.vo.AdminOperate;
import com.jic.point.mapper.ConfPlatformApplyMapper;
import com.jic.point.mapper.ConfPlatformMapper;
import com.jic.point.mapper.ConfPointCardBatchMapper;
import com.jic.point.model.entity.ConfPlatform;
import com.jic.point.model.entity.ConfPointCard;
import com.jic.point.model.entity.ConfPointCardBatch;
import com.jic.point.model.vo.request.ConfPointCardApplyRequest;
import com.jic.point.model.vo.request.QuantityRequest;
import com.jic.point.model.vo.response.ConfPointCardApplyResponse;
import com.jic.point.service.ConfPlatformService;
import com.jic.point.service.ConfPointCardBatchService;
import com.jic.point.utils.BeanUtil;
import com.jic.point.utils.CardUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.jic.point.constant.consist.ResponseCode;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.jic.common.base.vo.PageResult;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import javax.annotation.Resource;

import com.jic.point.exception.AppRuntimeException;
import com.jic.point.model.entity.ConfPointCardApply;
import com.jic.point.mapper.ConfPointCardApplyMapper;
import com.jic.point.service.ConfPointCardApplyService;

import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;

/**
 * 接口实现类
 *
 * @author : tzc
 * @version : v1.0.0
 * @email :
 * @since : 2020-03-09 10:12:20
 */
@Service
@Slf4j
public class ConfPointCardApplyServiceImpl implements ConfPointCardApplyService {

    @Resource
    private ConfPointCardApplyMapper mapper;

    @Resource
    private ConfPointCardBatchMapper batchMapper;

    @Resource
    private ConfPlatformMapper confPlatformMapper;

    @Resource
    private ConfPlatformApplyMapper confPlatformApplyMapper;

    /**
     * 新增记录
     *
     * @param request 需要保存的入参实体类
     * @return int 是否保存成功
     */
    @Override
    public int save(ConfPointCardApply request) {
        int flag = mapper.insert(request);
        if (flag == 1) {
            return 1;
        } else {
            throw new AppRuntimeException(ResponseCode.EXCEPTION, "新增失败");
        }
    }


    /**
     * 保存或修改记录信息
     *
     * @param request 需要保存的入参实体类
     * @return int 是否保存或修改成功
     * author tzc
     * @date 2020-3-11 20:54:09
     */
    @Override
    @Transactional
    public int saveOrUpdate(ConfPointCardApplyRequest request) {
        log.info("保存或修改记录信息，入参 = {}", JSONObject.toJSONString(request));
        try {
            if (request == null) {
                throw new AppRuntimeException(ResponseCode.EXCEPTION, "入参为空");
            }
            if (request.getId() != null) {
                log.info("保存或修改记录信息，修改，入参 = {}", JSONObject.toJSONString(request));
                ConfPointCardApply confPointCardApply = new ConfPointCardApply();
                BeanUtils.copyProperties(request,confPointCardApply);
                confPointCardApply.setUpdater(request.getAdminOperate().getOperator());
                confPointCardApply.setUpdaterName(request.getAdminOperate().getOperateName());
                int flag = mapper.updateByPrimaryKey(confPointCardApply);
                if (flag == 1) {
                    return 1;
                }
            } else {
                log.info("保存或修改记录信息，保存，入参 = {}", JSONObject.toJSONString(request));
                BigDecimal totalNumber=new BigDecimal(0); //总条数
                BigDecimal totalPoint=new BigDecimal(0); //总积分
                for (QuantityRequest item : request.getQuantity()) {
                    totalPoint = totalPoint.add(item.getTotalNum().multiply(item.getPointCardLimit()));
                    totalNumber = totalNumber.add(item.getTotalNum());
                }
                request.setTotalPoint(totalPoint);
                //先去平台中扣除积分，然后在进行申请
                ConfPlatform confPlatform = new ConfPlatform();
                confPlatform.setCode(request.getFirstDemandCode());
                confPlatform.setAvailable(totalPoint);
                //如果平台积分不足，就直接抛出异常返回到前端
                Long aLong = confPlatformMapper.updatePoint(confPlatform);
                if (aLong<1){
                    throw new AppRuntimeException(ResponseCode.NOT_POINT, "积分不足，添加失败");
                }
                request.setCode(CardUtils.random("Batch", 1).get(0));
                request.setAuditSts(0L);
                request.setDeleteFlag(0);
                request.setCreator(request.getAdminOperate().getOperator());
                request.setAuditOneSts(0L);
                ConfPointCardApply confPointCardApply = new ConfPointCardApply();
                BeanUtils.copyProperties(request,confPointCardApply);
                confPointCardApply.setQuantity(JSON.toJSON(request.getQuantity()).toString());
                confPointCardApply.setLeftNum(totalNumber);
                confPointCardApply.setTotalNum(totalNumber);
                confPointCardApply.setCardSort(request.getCardSort());
                int flag = mapper.insertSelective(confPointCardApply);
                if (flag == 1) {
                    return 1;
                } else {
                    throw new AppRuntimeException(ResponseCode.ELSE_REEOE, "修改失败");
                }
            }
        } catch (Exception e) {
            log.error("用户保存或修改失败", e);
            throw new AppRuntimeException(ResponseCode.EXCEPTION, "用户保存或修改失败");
        }
        return -1;
    }


    /**
     * 删除记录
     *
     * @param request 需要删除,含有主键的入参实体类
     * @return int 是否删除成功
     */
    @Override
    public int deleteByPrimaryKey(ConfPointCardApply request) {
        int flag = mapper.deleteByPrimaryKey(request);
        if (flag == 1) {
            return 1;
        } else {
            throw new AppRuntimeException(ResponseCode.EXCEPTION, "删除失败");
        }
    }


    /**
     * 逻辑删除记录
     *
     * @param request 含有主键的逻辑删除实体类
     * @return int 是否逻辑删除成功
     */
    @Override
    public int deleteByPrimaryKeyLogically(ConfPointCardApply request) {
        request.setDeleteFlag(1);
        int flag = mapper.deleteByPrimaryKey(request);
        if (flag == 1) {
            return 1;
        } else {
            throw new AppRuntimeException(ResponseCode.EXCEPTION, "逻辑删除记录失败");
        }
    }


    /**
     * 修改
     *
     * @param request
     * @return
     */
    @Override
    public int updateByPrimaryKeySelective(ConfPointCardApply request) {
        try {
            log.info("修改记录");
            request.setTotalPoint(request.getTotalNum().multiply(request.getPointCardLimit()));
            int flag = mapper.updateByPrimaryKeySelective(request);
            if (flag == 1) {
                return 1;
            } else {
                throw new AppRuntimeException(ResponseCode.EXCEPTION, "修改记录失败");
            }
        } catch (Exception e) {
            log.error("修改记录失败", e);
            throw new AppRuntimeException(ResponseCode.EXCEPTION, "修改记录失败");
        }

    }

    /**
     * 记录详情
     *
     * @param request 查询的入参实体类
     * @return 数据库查询到的实体类
     */
    @Override
    public ConfPointCardApply getByPrimaryKey(ConfPointCardApply request) {
        return mapper.selectByPrimaryKey(request);
    }


    /**
     * 分页查询
     *
     * @param request 分页查询入参实体类
     * @return 含有分页信息的实体类列表
     */
    @Override
    public PageInfo<ConfPointCardApplyResponse> listPageBySelective(ConfPointCardApplyRequest request, int pageNum, int pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        PageHelper.orderBy(" create_time desc");
        request.setDeleteFlag(0);
        if (request.getExpiration()!=null &&request.getExpiration().size()>1){
            request.setMinExpiration(request.getExpiration().get(0));
            request.setExpiryTime(request.getExpiration().get(1));
        }
        List<ConfPointCardApply> list = mapper.listPageBySelective(request);
        List<ConfPointCardApplyResponse> collect = list.stream().map(item -> {
            ConfPointCardApplyResponse confPointCardApplyResponse = new ConfPointCardApplyResponse();
            BeanUtils.copyProperties(item, confPointCardApplyResponse);
            confPointCardApplyResponse.setQuantity(JSONObject.parseArray(item.getQuantity(),QuantityRequest.class));
            return confPointCardApplyResponse;
        }).collect(Collectors.toList());
        PageInfo pageInfo = new PageInfo(collect);
        PageResult<ConfPointCardApplyResponse> result = new PageResult<>();
        result.setTotal(pageInfo.getTotal());
        result.setRows(collect);
        return new PageInfo(collect);
    }

    /**
     * 不分页查询
     *
     * @param request 不分页查询入参实体类
     * @return 数据库查到的实体类列表
     */
    @Override
    public List<ConfPointCardApply> listAllRecord(ConfPointCardApply request) {
        //分页处理
        request.setDeleteFlag(0);
        return mapper.selectBySelective(request);
    }

    /**
     * 核审批量插入
     * name：fr  date：2020/10/29
     */
    @Override
    @Transactional
    public Integer listUpdate(List<ConfPointCardApplyRequest> request, AdminOperate adminOperate) {
        log.error("批量审核开始，参数"+request.toString(),adminOperate.toString());
        int i = 0;
        for (ConfPointCardApplyRequest confPointCardApplyRequest : request) {
            ConfPointCardApply apply = new ConfPointCardApply();
            apply.setAuditorId(confPointCardApplyRequest.getAuditorId());
            apply.setAuditSts(confPointCardApplyRequest.getAuditSts());
            apply.setId(confPointCardApplyRequest.getId());
            apply.setAuditTime(new Date());
            apply.setAuditorId(adminOperate.getOperator());
            apply.setAuditReason(confPointCardApplyRequest.getAuditReason());
            apply.setAuditTime(new Date());
            if (adminOperate.getOperator() != null && adminOperate.getOperator() > 0) {
                apply.setAuditorId(adminOperate.getOperator());
            }
            if (confPointCardApplyRequest.getAuditSts()==1){
                //先将平台中的积分扣除
                confPlatformMapper.addPoint(confPointCardApplyRequest.getFirstDemandCode(),confPointCardApplyRequest.getTotalPoint());
            }
            apply.setDeleteFlag(1);
            //将状态修改
            i = mapper.updateByPrimaryKey(apply);
            if (i <= 0) {
                throw new AppRuntimeException(ResponseCode.EXCEPTION, "核审失败");
            } else if (apply.getAuditSts() != null && apply.getAuditSts() == 2 && i > 0) {
                ConfPointCardBatch batch = new ConfPointCardBatch();
                BeanUtils.copyProperties(confPointCardApplyRequest, batch);
                batch.setTotalPoint(confPointCardApplyRequest.getTotalPoint());
                batch.setLeftPoint(batch.getTotalPoint());
                batch.setId(null);
                batch.setCardSort(confPointCardApplyRequest.getCardSort());
                batch.setType(confPointCardApplyRequest.getType());
                batch.setPurchaseType(confPointCardApplyRequest.getPurchaseType());
                batch.setQuantity(JSON.toJSON(confPointCardApplyRequest.getQuantity()).toString());
                batch.setAuditorId(adminOperate.getOperator());
                batch.setAuditTime(new Date());
                int insert = batchMapper.insertSelective(batch);
                if (insert <= 0) {
                    throw new AppRuntimeException(ResponseCode.EXCEPTION, "核审失败");
                }
            }
        }
        log.error("批量审核结束，参数"+(i>0));
        return i;
    }

    @Override
    public Integer delaying(ConfPointCardApplyRequest request) {
        List<ConfPointCardApply> collect = request.getList().stream().map(item -> {
            ConfPointCardApply confPointCardApply = new ConfPointCardApply();
            Calendar rightNow = Calendar.getInstance();
            rightNow.setTime(item.getExpiryTime());
            switch (request.getTimeUnit()) {
                case "year":
                    rightNow.add(Calendar.YEAR, request.getTime());
                    break;
                case "month":
                    rightNow.add(Calendar.MONTH, request.getTime());
                    break;
                case "day":
                    rightNow.add(Calendar.DAY_OF_MONTH, request.getTime());
                    break;
                case "hour":
                    rightNow.add(Calendar.HOUR, request.getTime());
                    break;
                case "week":
                    rightNow.add(Calendar.WEEK_OF_MONTH, request.getTime());
                    break;
                case "minute":
                    rightNow.add(Calendar.MINUTE, request.getTime());
                    break;
            }
            confPointCardApply.setId(item.getId());
            confPointCardApply.setExpiryTime(rightNow.getTime());
            return confPointCardApply;
        }).collect(Collectors.toList());
        Integer i = mapper.listUpdate(collect);
        if (i<0){
            throw new AppRuntimeException(ResponseCode.EXCEPTION, "延期失败");
        }
        return i;
    }

    /**
     * 实现批量一审
     *
     * @param request      查询入参实体类
     * @return 实体类列表
     */
    @Override
    @Transactional
    public Integer firstInstance(ConfPointCardApplyRequest request) {
        List<ConfPointCardApply> collect = request.getList().stream().map(item -> {
            ConfPointCardApply confPointCardApply = new ConfPointCardApply();
            confPointCardApply.setId(item.getId());
            confPointCardApply.setAuditorOneId(request.getAdminOperate().getOperator());
            confPointCardApply.setAuditOneReason(request.getAuditOneReason());
            confPointCardApply.setAuditOneSts(request.getAuditOneSts());
            //如果审核不通过 就将申请积分卡数据中的积分退还给平台
            if (confPointCardApply.getAuditOneSts()==1){
                confPointCardApply.setDeleteFlag(1);
                Integer integer = confPlatformMapper.addPoint(item.getFirstDemandCode(), item.getTotalPoint());
            }
            return confPointCardApply;
        }).collect(Collectors.toList());
        Integer result = mapper.batchReview(collect);
        if (result<=0){
            throw new AppRuntimeException(ResponseCode.EXCEPTION, "核审失败");
        }
        return result;
    }
}
